/**
 * @class   wosh::NetworkProtocol
 * @brief   Interface of a generic communication protocol, handles properties
 *          and manager (dis)connection of custom wosh::NetworkChannel
 *
 * @see     wosh::NetworkChannel
 * @see     wosh::NetworkManager
 ****************************************************************************
 * @version $Id: NetworkProtocol.h 2827 2010-08-02 11:01:48Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
/* Copyright (c) 2007-2010, WOSH - Wide Open Smart Home 
 * by Alessandro Polo - OpenSmartHome.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the OpenSmartHome.com WOSH nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY Alessandro Polo ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Alessandro Polo BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR UserS;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ****************************************************************************/

#ifndef __WOSH_Core_NetworkProtocol_H__
 #define __WOSH_Core_NetworkProtocol_H__

 #include <woshDefs.h>
 #include <core/Object.h>
 #include <core/PropertiesProvider.h>
 #include <core/MethodsProvider.h>
 #include <core/Bus.h>
 #include <core/LogContext.h>
 #include <core/WoshHost.h>

 #include <vector>


namespace wosh {

 #define _NetworkProtocol_KEY_ProtocolPrefix		"ProtocolPrefix"
 #define _NetworkProtocol_KEY_Priority				"Priority"

 #define _NetworkProtocol_KEY_ServersCount			"ServersCount"
 #define _NetworkProtocol_KEY_ClientsCount			"ClientsCount"

 #define _NetworkProtocol_METHOD_listen				"listen"
 #define _NetworkProtocol_METHOD_connect			"connect"

// #define _NetworkChannel_EVENT_ListChanged			"NetworkChannel_ListChanged"
 #define _NetworkProtocol_EVENT_ConnectionChanged	"NetworkProtocol_ConnectionChanged"


class NetworkProtocol;
class NetworkManager;
class BusManager;
class NetworkChannel;
template <class T> class DataFieldCollector;

class INetworkProtocolListener
 {
	public:
		virtual void network_protocol_supported( const std::string& protocol_string, NetworkChannel* channel, NetworkProtocol* source ) = 0;
		virtual void network_protocol_new_channel( NetworkChannel* channel, short in_out, NetworkProtocol* source ) = 0;

	public:
		virtual ~INetworkProtocolListener() { }

};


class NetworkProtocol :	public Object,
						public virtual IPropertiesProviderListener,
						public MethodRunner
 {
	WOSH_CLASSNAME(wosh::NetworkProtocol)
	WOSH_CLASS_ABSTRACT(true)

	public:
		/**
		 * @brief  Empty constructor.
		 */
		NetworkProtocol();
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~NetworkProtocol();


/** @name NetworkProtocol interface
 * @{
 ******************************************************************************/
	public:
		virtual bool supportProtocol( const std::string& protocol_string ) const = 0;

		virtual WRESULT listenChannel( const std::string& protocol_string, unsigned long timeout = LIMIT_ULONG_MAX ) = 0;

		virtual WRESULT connectChannel( const std::string& protocol_string, unsigned long timeout = LIMIT_ULONG_MAX ) = 0;

		virtual WRESULT connectChannel( const std::vector<std::string>& protocolsAvailable, unsigned long timeout = LIMIT_ULONG_MAX ) = 0;

//@}
/** @name Getters
 * @{
 ******************************************************************************/
	public:
		virtual const char* getProtocolPrefix() const = 0;

		virtual int getPriority() const = 0;

		virtual int getServersCount() const = 0;
		virtual int getClientsCount() const = 0;

		const PropertiesProvider& getProperties() const { return Properties; }
		PropertiesProvider& getProperties()				{ return Properties; }

		const MethodsProvider& getMethods() const		{ return this->Methods; }
		MethodsProvider& getMethods()					{ return this->Methods; }

		static DataFieldCollector<NetworkProtocol>* getDataFields();

//@}
/** @name Setters
 * @{
 ******************************************************************************/
	public:
		WRESULT setListener( INetworkProtocolListener* npl );
//@}
/** @name IPropertiesProviderListener interface
 * @{
 ******************************************************************************/
 	public:
		virtual bool readingProperty( Property*, const PropertiesProvider* ) { return true; }
		virtual bool updatingProperty( bool& do_update, const Variant& value_proposed, Property& property_current, const PropertiesProvider* source );
//@}
	private:
		Response* mmDoConnect( const Request* request );
		Response* mmDoListen( const Request* request );

	protected:
		mutable PropertiesProvider Properties;	///< my configuration
		mutable MethodsProvider Methods;		///< my methods
		mutable LogContext Log;					///< my logger

		INetworkProtocolListener* listener;		///< class listening for events

		friend class NetworkManager;			///< my big brother


}; // class def







/**
 * @class   wosh::NetworkProtocol_ListChanged
 * @brief   Raised when 
 *
 * Internally, data is stored as wosh::Variant (STRING).
 *
 * Fields are:
 *  - \c 
 *

 * \code
 * \endcode
 *
 * @see     wosh::Fact
 * @see     wosh::WoshHost
 ****************************************************************************
 * @version 0.8.399 $Id: NetworkProtocol.h 2827 2010-08-02 11:01:48Z alex $
 * @author  Alessandro Polo
 ****************************************************************************/
class NetworkProtocol_ListChanged : public Fact
 {
	WOSH_SERIALIZABLE(wosh::NetworkProtocol_ListChanged)

	public:
		/**
		 * @brief  Empty constructor.
		 */
		NetworkProtocol_ListChanged()
			: Fact( _NetworkProtocol_EVENT_ConnectionChanged ) { }
		/**
		 * @brief  Constructor with initializers.
		 * @param woshname [in] the subject (host) of the event
		 */
		NetworkProtocol_ListChanged( const std::string& network_protocol_name, int action );
		/**
		 * @brief  Copy constructor.
		 * @param m [in] the source object to be copied
		 */
		NetworkProtocol_ListChanged( const NetworkProtocol_ListChanged& m )
			: Fact(m) { }
		/**
		 * @brief  Empty destructor.
		 */
		virtual ~NetworkProtocol_ListChanged() { }

	public:
		std::string getNetworkProtocolName() const;
		int getListAction() const;

}; // class def








}; // namespace wosh

#endif //__WOSH_Core_NetworkProtocol_H__
